package com.ruicar.afs.cloud.basic.proceeds.debit.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruicar.afs.cloud.basic.common.entity.BasicReceiptRecord;
import com.ruicar.afs.cloud.basic.common.service.BasicMainInfoService;
import com.ruicar.afs.cloud.basic.common.service.BasicReceiptRecordService;
import com.ruicar.afs.cloud.basic.proceeds.debit.entity.BasicDebitBatch;
import com.ruicar.afs.cloud.basic.proceeds.debit.entity.BasicDebitBatchDetails;
import com.ruicar.afs.cloud.basic.proceeds.debit.entity.BasicDebitHistory;
import com.ruicar.afs.cloud.basic.proceeds.debit.entity.BasicDebitRecord;
import com.ruicar.afs.cloud.basic.proceeds.debit.mapper.BasicDebitBatchDetailsMapper;
import com.ruicar.afs.cloud.basic.proceeds.debit.service.BasicDebitBatchDetailsService;
import com.ruicar.afs.cloud.basic.proceeds.debit.service.BasicDebitHistoryService;
import com.ruicar.afs.cloud.basic.proceeds.debit.service.BasicDebitRecordService;
import com.ruicar.afs.cloud.basic.proceeds.mq.sender.FinanceSender;
import com.ruicar.afs.cloud.common.core.security.service.AfsUser;
import com.ruicar.afs.cloud.common.core.security.util.SecurityUtils;
import com.ruicar.afs.cloud.common.modules.constant.VoucherBuriedPointNo;
import com.ruicar.afs.cloud.common.modules.contract.enums.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @author: Lee
 * @date 2020-05-30 04:35:07 
 * @description 
 */
@Service
@ConditionalOnProperty(prefix = "com.ruicar.afs.cloud.mq.rabbit",name="enable")
public class BasicDebitBatchDetailsServiceImpl extends ServiceImpl<BasicDebitBatchDetailsMapper, BasicDebitBatchDetails> implements BasicDebitBatchDetailsService {
    @Autowired
    private BasicDebitRecordService basicDebitRecordService;
    @Autowired
    private BasicDebitHistoryService basicDebitHistoryService;
    @Autowired
    private BasicReceiptRecordService basicReceiptRecordService;
    @Autowired
    private FinanceSender financeSender;
    @Autowired
    private  BasicMainInfoService mainInfoService;

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = Exception.class)
    public void debitSuccess(BasicDebitBatch debitBatch, BasicDebitBatchDetails debitBatchDetails, String message, String creditAccount,String creditBankName,String creditOpeningBankName, Date batchDate) {
        List<BasicDebitRecord> debitRecordList = basicDebitRecordService.list(Wrappers.<BasicDebitRecord>query().lambda()
                .eq(BasicDebitRecord::getBatchId,debitBatchDetails.getBatchId())
                .eq(BasicDebitRecord::getContractNo,debitBatchDetails.getContractNo())
        );
        /**  核销目的 by ZC.GUO  **/
        WriteTargetTypeEnum writeTarget = WriteTargetTypeEnum.normal;
        if (CollectionUtils.isNotEmpty(debitRecordList)){
            for (BasicDebitRecord debitRecord:debitRecordList){
                /**  明确核销目的 by ZC.GUO  **/
                if (FeeTypeEnum.advanceSettle.equals(debitRecord.getFeeType())){
                    writeTarget = WriteTargetTypeEnum.beforeCharge;
                }
                /**  更新扣款历史表 by ZC.GUO  **/
                BasicDebitHistory debitHistory = basicDebitHistoryService.getOne(Wrappers.<BasicDebitHistory>query().lambda()
                        .eq(BasicDebitHistory::getBatchId,debitBatch.getId())
                        .eq(BasicDebitHistory::getRecordId,debitRecord.getId())
                );
                if (ObjectUtils.isNotEmpty(debitHistory)){
                    debitHistory.setBackTime(batchDate);
                    debitHistory.setDebitResult(DebitStatusEnum.successDebit);
                    basicDebitHistoryService.updateById(debitHistory);
                }

                /**  更新待扣款数据 by ZC.GUO  **/
                debitRecord.setSucceedAmt(debitRecord.getSucceedAmt().add(debitRecord.getGoingAmt()));
                debitRecord.setGoingAmt(BigDecimal.ZERO);
                debitRecord.setWriteOffAmt(debitRecord.getSucceedAmt());
                if (debitRecord.getSucceedAmt().compareTo(debitRecord.getReadyAmt()) == 0){
                    debitRecord.setDebitStatus(DebitStatusEnum.completeDebit);
                }else{
                    debitRecord.setDebitStatus(DebitStatusEnum.mayDebit);
                }
                basicDebitRecordService.updateDebitRecordSucceed(debitRecord);
            }
        }
        /**  修改批次明细 by ZC.GUO  **/
        debitBatchDetails.setStatus(DebitStatusEnum.successDebit);
        debitBatchDetails.setRemarks(message);
        debitBatchDetails.setCreditAccount(creditAccount);
        debitBatchDetails.setCreditBankName(creditBankName);
        debitBatchDetails.setCreditOpeningBankName(creditOpeningBankName);
        debitBatchDetails.setCompleteDate(Calendar.getInstance().getTime());
        this.updateById(debitBatchDetails);

        /**  收据初始化 by ZC.GUO  **/
        BasicReceiptRecord basicReceiptRecord = basicReceiptRecordService.initReceiptRecordOfDebit(debitBatchDetails,writeTarget,batchDate);

        /**  发送扣款成功数据到账务服务MQ by ZC.GUO  **/
        AfsUser user= SecurityUtils.getUser();
        String operator = user == null?null:user.getUsername();
        String buriedPointNo=null;
        if(WriteTargetTypeEnum.beforeCharge.equals(basicReceiptRecord.getWriteTarget())){
            buriedPointNo=VoucherBuriedPointNo.withholdSettlementAdvance;
        }else{
            buriedPointNo=VoucherBuriedPointNo.contractWithhold;
        }
        basicReceiptRecordService.sendDebitSuccessDataToFinance(basicReceiptRecord, TransOpreateTypeEnums.debit,buriedPointNo,operator);

        /**  更新收据状态 by ZC.GUO  **/
        basicReceiptRecord.setReceiptStatus(ReceiptStatusEnum.creditSuccess);
        basicReceiptRecordService.updateById(basicReceiptRecord);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = Exception.class)
    public void debitFailed(BasicDebitBatch debitBatch,BasicDebitBatchDetails debitBatchDetails,String message, Date batchDate) {
        List<BasicDebitRecord> debitRecordList = basicDebitRecordService.list(Wrappers.<BasicDebitRecord>query().lambda()
                .eq(BasicDebitRecord::getBatchId,debitBatchDetails.getBatchId())
                .eq(BasicDebitRecord::getContractNo,debitBatchDetails.getContractNo())
        );
        if (CollectionUtils.isNotEmpty(debitRecordList)){
            for (BasicDebitRecord debitRecord:debitRecordList){
                /**  更新扣款历史表 by ZC.GUO  **/
                BasicDebitHistory debitHistory = basicDebitHistoryService.getOne(Wrappers.<BasicDebitHistory>query().lambda()
                        .eq(BasicDebitHistory::getBatchId,debitBatch.getId())
                        .eq(BasicDebitHistory::getRecordId,debitRecord.getId())
                );
                if (ObjectUtils.isNotEmpty(debitHistory)){
                    debitHistory.setBackTime(batchDate);
                    debitHistory.setDebitResult(DebitStatusEnum.failDebit);
                    basicDebitHistoryService.updateById(debitHistory);
                }
                /**  更新待扣款数据 by ZC.GUO  **/
                debitRecord.setGoingAmt(BigDecimal.ZERO);
                debitRecord.setDebitStatus(DebitStatusEnum.mayDebit);
                debitRecord.setBatchId(null);
                if(DebitModeEnum.manual.equals(debitBatch.getDebitMode())){
                    debitRecord.setManualNum(debitRecord.getManualNum()+1);
                }
                basicDebitRecordService.updateDebitRecordFailed(debitRecord);
            }
        }
        /**  修改批次明细 by ZC.GUO  **/
        debitBatchDetails.setStatus(DebitStatusEnum.failDebit);
        debitBatchDetails.setRemarks(message);
        debitBatchDetails.setCompleteDate(Calendar.getInstance().getTime());
        this.updateById(debitBatchDetails);
    }

    @Override
    public void debitNoResult(BasicDebitBatchDetails debitBatchDetails) {
        /**  无需修改待扣款明细 by ZC.GUO  **/
        /**  修改批次明细 by ZC.GUO  **/
        debitBatchDetails.setStatus(DebitStatusEnum.noResult);
        this.updateById(debitBatchDetails);
    }
}
